﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace DataProcess.Core.DataAccess
{
    public class DbContext<T> where T : class, new()
    {

        public static string SqliteStr = @"DataSource=" + AppDomain.CurrentDomain.BaseDirectory + @"DataProcess.db";

        /// <summary>
        /// 初始化数据库操作/MSSQL
        /// </summary>
        /// <param name="connStr">链接字符串</param>
        /// <param name="dbType">数据库类型。0,1,2,3,4中的一个,其中
        /// MySql = 0,
        /// SqlServer = 1,
        /// Sqlite = 2,
        /// Oracle = 3,
        /// PostgreSQL = 4
        /// </param>
        public DbContext(string connStr = "", int dbType = 2)
        {
            Db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = string.IsNullOrEmpty(connStr) ? SqliteStr : connStr,
                DbType = (DbType)dbType,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.SystemTable,
                MoreSettings = new ConnMoreSettings { IsWithNoLockQuery = true }
            });
        }

        /// <summary>
        /// 用于数据库操作
        /// </summary>
        private SqlSugarClient Db { get; set; }

        public SimpleClient<T> CurrentDb { get { return new SimpleClient<T>(Db); } }
    }

    public static class DbContextExtension
    {
        /// <summary>
        /// 将数据保存至数据库
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool Save<T>(this T t) where T : class, new()
        {
            DbContext<T> dbContext = new DbContext<T>();
            return dbContext.CurrentDb.AsInsertable(t).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 从数据库中更新数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool Update<T>(this T t) where T : class, new()
        {
            DbContext<T> dbContext = new DbContext<T>();
            return dbContext.CurrentDb.AsUpdateable(t).ExecuteCommand() > 0;
        }

        public static bool UpdateColumns<T>(this T t, Expression<Func<T, object>> expr) where T : class, new()
        {
            DbContext<T> dbContext = new DbContext<T>();
            return dbContext.CurrentDb.AsUpdateable(t).UpdateColumns(expr).ExecuteCommand() > 0;
        }

        public static bool UpdateColumns<T>(this List<T> list, Expression<Func<T, object>> expr) where T : class, new()
        {
            if (list.Count == 0) return true;
            DbContext<T> dbContext = new DbContext<T>();
            return dbContext.CurrentDb.AsUpdateable(list.ToArray()).UpdateColumns(expr).ExecuteCommand() > 0;
        }

        public static bool DeleteByIds<T>(this List<T> list, dynamic[] ids) where T : class, new()
        {
            if (list.Count == 0) return true;
            DbContext<T> dbContext = new DbContext<T>();
            return dbContext.CurrentDb.DeleteByIds(ids);
        }

        public static List<T> Get<T>(this DbContext<T> context) where T : class, new()
        {
            return context.CurrentDb.GetList();
        }

        public static List<T> Get<T>(this DbContext<T> context, Expression<Func<T, bool>> whereExpression) where T : class, new()
        {
            return context.CurrentDb.GetList(whereExpression);
        }

        public static T GetFirst<T>(this DbContext<T> context, Expression<Func<T, bool>> whereExpression) where T : class, new()
        {
            return context.CurrentDb.AsQueryable().First(whereExpression);
        }
    }
}
